
jQuery.fn.autocomplete = function(url, options) {
	options = options||{};
	options.url = url;
	this.each(function() {
		new jQuery.autocomplete(this, options);
	});
	return this;
}
jQuery.autocomplete = function(input, options) {
	var input = $(input).attr("autocomplete", "off");
	var requests = new Array();
	options.delay = false;
	options.onSelect = options.onSelect||function(){};
	options.onShow = options.onShow||function(item){ return ""; };

	var results = $(document.createElement("div"));
	input.parents('div:first').append(results);
	results.addClass("autocomplete").css("position", "absolute");
	
	var hideIt = false;
	
	input.bind('keyup', function(e)	{
		var search = input.val();
		if (options.delay) return;
		options.delay = true;
		setTimeout(function(){options.delay=false;}, 50);
		if(e.keyCode == 46 || (e.keyCode > 8 && e.keyCode < 32) || search.length < 2  ) return results.hide();

		switch(e.keyCode) {
			case 38: // up
				break;
			case 40: // down
				break;
			case 9:  // tab
			case 13: // return
				break;
			default:
				break;
		}
		
		if (requests[search] != null){
			onResult(requests[search], search);
		} else	{
			$.post(options.url, { search: search }, function(data) {
				json = $.parseJSON(data);
				requests[search] = json;
				onResult(json, search);
			});
		}
	}).click(function(e)	{
		if (requests[input.val()] != null){
			results.show();
			e.preventDefault(); e.stopPropagation();
		}
	});
	
	$('body').click(function(){
		results.hide();
	});
	
	function onResult(json, search)	{
		results.html('');
		results.css({
			width: input.parents('div:first').width() + "px",
			//top: (input.offset().top + input.height() + 2) + "px",
			//left: (input.offset().left + 2) + "px",
			background: "#CCC"
		}).show();
		
		for(var i=0;i<json.length;i++){
			var item = $(document.createElement("div"));
			results.append(item);
			item.html(options.onShow(json[i]));
			item.attr('index', i).addClass("item");
			item.click(function(e){
				clearTimeout(hideIt);
				e.preventDefault(); e.stopPropagation();
				results.hide();
				options.onSelect(json[$(this).attr('index')]);
			});
		}
		
	}

	function offset(obj) {
		var curleft = obj.offsetLeft || 0;
		var curtop = obj.offsetTop || 0;
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
		return {x:curleft,y:curtop};
	}
}